<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <button>按钮1</button>
    <button>按钮2</button>
    <script>
        // 1.JS延迟加载的方式有哪些？（5）
        // async：加载和渲染后文档元素的过程将和外部js的加载和执行并且进行异步加载
        // defer：等待加载和渲染后文档元素之后，外部js才会引入进来
        // 把js外部引入的文件放到页面底部，来让js最后引入，从而加快页面加载速度

        // 2.前端 JavaScript 中的 ECMAScript、DOM、BOM 的含义；
        // ECMAScript：JavaScript的核心，规定了JS的语法规范
        // DOM：文档对象模型（提供与网页内容交互的方法和接口）
        // BOM：浏览器对象模型（提供与浏览器交互的方法和接口）

        // 3.JavaScript 的数据类型有哪些？
        // 简单数据类型：number、boolean、string、undefined、null、symbol
        //引用数据类型：Array、Object、Function

        // 4.如何进行数据类型的判断？
        //typeof 检测的数据
        //检测的数据 instanceof 构造函数
        //Object prototype string call(检测的数据)


        // 5.null 和 undefined 的区别？什么时候会得到 undefined？
        //null 空对象，空的对象指针，但null!={}
        //undefined 声明变量但没有赋值，表无意义


        // 6.如何理解 null == undefined 返回 true，null === undefined 返回 false？
        // null==undefined 判断值，两者的布尔值都是false
        // null===undefined 判断值和数据类型

        // 7.使用 continue 或 break 终止循环时，两种方式的区别是？
        //continue 是停止当前循环，执行下一个循环
        //break 终止整个循环流程

        // 8.如何判断字符串内是否包含指定字符？
        // indexOf()：如果有指定字符，则返回对应的索引值，否则返回-1
        // lastIndexOf()：如果有指定字符，则返回对应的索引值，否则返回-1
        // includes()：如果有指定字符，则返回true，否则返回false

        // 9.请尽量列举出数组的方法，并且注明哪些方法会修改原数组，哪些不会；
        // 不会改变原数组：
        // join
        // concat
        // slice
        // indexOf
        // lastIndexOf
        // includes

        // 会改变原数组：
        // splice
        // reverse
        // push
        // unshift
        // pop
        // shift

        // 10. var、let、const 区别？
        // var
        // 可以声明变量
        // 支持变量提升
        // 支持重复声明
        // 不存在块级作用域

        // let
        // 可以声明变量
        // 不支持变量提升
        // 不支持重复声明
        // 存在块级作用域

        // const
        // 可以声明常量
        // 不允许常量进行修改
        // 不支持重复声明
        // 存在块级作用域

        // 12. 如何在 DOM2 级事件绑定上传递参数？
        let button1 = document.querySelectorAll("button")[0];
        button1.addEventListener("click", sum(12, 8));

        function sum(a, b) {
            return function() {
                console.log(a + b);
            }
        }

        // 13. 怎么阻止事件的进一步传播和默认事件？
        // 阻止冒泡：event,stopPropagation()
        // 阻止默认事件：event.preventDefault() 

        // 14. 如何添加一个一次性事件？
        let button2 = document.querySelectorAll("button")[1];

        // 方法1：
        button2.addEventListener("click", function() {
            console.log("我只能被执行一次");
        }, {
            once: true
        });

        // // 方法2：
        // button2.addEventListener("click", fn2);

        // function fn2() {
        //     console.log("我只能被执行一次");
        //     button2.removeEventListener("click", fn2);
        // };

        // 15. 同步和异步的区别?
        // 同步：在主线程上排队执行的任务，只有前一个任务执行完毕，才能执行后一个任务
        // 异步：不进入主线程、而进入"任务队列"的任务，只有等主线程任务执行完毕，"任务队列"开始通知主线程，请求执行任务，该任务才会进入主线程执行

        // 16. AJAX是什么？AJAX是如何为页面注入灵魂？
        // AJAX 是一种在无需重新加载整个网页的情况下，能够更新部分网页的技术。
        // AJAX 是一种用于创建快速动态网页的技术。
        // AJAX 通过在后台与服务器进行少量数据交换， 使网页实现异步更新。 这意味着可以在不重载整个页面的情况下， 对网页的某些部分进行更新。
        // 传统的网页（ 不使用 AJAX） 如果需要更新内容， 必须重载整个页面。

        // 17. 开发阶段的 AJAX 跨域有哪些解决方法，jsonp 的原理是什么
        // 前端解决跨域：JSONP，出现的早，兼容性好（兼容低版本IE）。是前端程序员为了解决跨域问题，被迫想出来的一种临时解决方案。缺点是只支持 GET 请求，不支持 POST 请求
        // 后端解决跨域：后端设置响应头Response Headers，设置白名单，"Access-Control-Allow-Origin":"指定的域名地址"||*
        // JSONP 的原理：
        // 由于浏览器同源策略的限制，网页中无法通过 Ajax 请求非同源的接口数据。但是 <script> 标签不受浏览器同源策略的影响，可以通过 src 属性，请求非同源的 js 脚本
        // JSONP 的实现原理，就是通过 <script> 标签的 src 属性，请求跨域的数据接口，并通过函数调用的形式，接收跨域接口响应回来的数据

        // 18. 请描述一下cookies，sessionStorage和localStorage的区别
        // cookie：
        // 浏览器在本地按照一定规律存储一些文本字符串，每当浏览器向服务器发送请求的携带这些字符，服务器就会根据字符串去判断浏览器的信息（状态），比如登录、订单、浏览记录，服务器就可以根据不同的cookie识别出不同的信息
        // 可以设置cookie过期时间
        // 限制大小为4kb左右，超出部分会被裁切

        // localStorage：
        // 1、用于长久保留整个网页的数据，除非手动删除，否则关闭页面也会存在
        // 2、可以多窗口（页面）共享（同一浏览器可以共享）
        // 3、以键值对的形式存储使用

        // sessionStorage
        // 1、生命周期为关闭浏览器窗口
        // 2、在同一个窗口(页面)下数据可以共享
        // 3、以键值对的形式存储使用

        // 19. 讲一下常见的异步场景，以及传统异步的诟病和解决方案

        // 20. 数组如何实现去重？请提供至少2种方法
        //方法一：
        // let arr = ['a', 'b', 'a', 'c', 'd', 'c', 'c'];
        // let newArr = [];
        // for (let i = 0; i < arr.length; i++) {
        //     if (newArr.indexOf(arr[i]) == -1) {
        //         newArr.push(arr[i]);
        //     }
        // }
        // console.log(newArr);

        // 方法二：ES6 new Set()
        // let arr = ['a', 'b', 'a', 'c', 'd', 'c', 'c'];
        // console.log(new Set(arr));

        // 21. 讲一下对基本数据类型 和 复杂/引用数据类型的理解？
        // 基本数据类型的存储方式：存放在栈里面，里面直接开辟一个空间存放的是值
        // 引用数据类型的存储方式：首先在栈里面存放地址，十六进制表示，然后这个地址指向堆里面的数据

        // 22. this 的指向如何确定？

        // 23. 谈谈对垃圾回收机制的认识
        // 垃圾回收：js代码想要运行，需要操作系统或者运行时提供内存空间，来存储变量及它的值。在某些变量（例如局部变量）在不参与运行时，就需要系统回收被占用的内存空间，称为垃圾回收

        // 24. 什么是回流重绘，如何进行优化？
        //  回流：当render tree的一部分或者全部元素因改变了自身的宽高，布局，显示或隐藏，或元素内部的文字结构发生变化，导致需要重新构建页面的时候，回流就产生了。
        // 重绘：当一个元素自身的宽高，布局，及显示或隐藏没有改变，而只是改变了元素的外观风格的时候，就产生了重绘。
        // 结论：回流必定触发重绘，而重绘不一定出发回流。
        // 优化：
        // 1、不使用能够触发回流的属性；
        // 2、建立一个图层，让回流在图层里面进行，限制回流和重绘的范围，减少浏览器的运算工作量。

        // 25. 请解释什么是事件代理
        // 事件代理的实现原理是利用冒泡和目标元素，把处理的事件添加到父元素，等待子元素事件的冒泡，并且可以通过父元素event.target判断哪个是子元素，从而做出处理

        // 26. 谈谈你对渐进增强和优雅降级的理解(补充)
        // 渐进增强：一开始就针对低版本浏览器进行构建页面，完成基本的功能，然后再针对高级浏览器进行效果、交互、追加功能达到更好的体验。
        // 优雅降级：一开始就构建站点的完整功能，然后针对浏览器测试和修复。比如一开始使用 CSS3 的特性构建了一个应用，然后逐步针对各大浏览器进行 hack 使其可以在低版本浏览器上正常浏览。
    </script>
</body>

</html>